package com.aizuda.easyManagerTool.service.terminal.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.aizuda.easyManagerTool.domain.dto.terminal.SSHMessageDTO;
import com.aizuda.easyManagerTool.domain.vo.socket.SocketMessageVO;
import com.jcraft.jsch.ChannelShell;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

@Slf4j
public abstract class AbstractSSHTemplate extends  AbstractTerminalTemplate{
    SocketMessageVO<String> socketMessageVO = new SocketMessageVO<String>();


    public void sendMessage(TerminalSessionManager.Manager manager,ChannelShell channelShell, WebSocketSession message, String type) {
        InputStream inputStream = null;
        try {
            inputStream = channelShell.getInputStream();
            //循环读取
            byte[] buffer = new byte[1024];
            int i = 0;
            //如果没有数据来，线程会一直阻塞在这个地方等待数据。
            SocketMessageVO<String> messageVO = BeanUtil.copyProperties(socketMessageVO, SocketMessageVO.class );
            messageVO.setType(type);
            while ((i = inputStream.read(buffer)) != -1) {
                String str = new String(Arrays.copyOfRange(buffer, 0, i), StandardCharsets.UTF_8);
                manager.appendLog(str);
                messageVO.setObj(str);
                synchronized (message) {
                    message.sendMessage(new TextMessage(JSONUtil.toJsonStr(messageVO)));
                }
            }
        } catch (Exception e){
            if(e instanceof InterruptedException || e instanceof InterruptedIOException){
                log.debug("线程中断");
                return;
            }
            log.error("终端发送数据失败 {}",e.getMessage());
        }finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            }catch(Exception e){}
        }
    }

    @Override
    void init(String token,WebSocketSession message, TerminalSessionManager.Manager manager, SSHMessageDTO messageDTO) throws Exception {

    }

    @Override
    void connect(TerminalSessionManager.Manager manager, SSHMessageDTO messageDTO) throws Exception {

    }

    @Override
    void close(TerminalSessionManager.Manager manager) {

    }

    /**
     * 方法无法使用，在已经进行交互的线程中如果使用此方法，会占用InputStream，导致其他线程无法检测到 输入流的内容
     * @param channelShell
     * @param command
     * @return
     * @throws IOException
     */
    public String extractChannelShellStr(ChannelShell channelShell,String command) throws IOException {
        // 获取上传路径
        InputStream is = channelShell.getInputStream();
        setCommand(channelShell,command);
        //循环读取
        byte[] buffer = new byte[2048];
        int k = 0;
        String str = null;
        //如果没有数据来，线程会一直阻塞在这个地方等待数据。
        while ((k = is.read(buffer)) != -1) {
            str = new String(Arrays.copyOfRange(buffer, 0, k), StandardCharsets.UTF_8);
            break;
        }
        return str;
    }

    public void setCommand(ChannelShell channelShell,String command) throws IOException {
        OutputStream outputStream  = channelShell.getOutputStream();
        outputStream.write(command.getBytes());
        outputStream.flush();
    }

}
